home *** CD-ROM | disk | FTP | other *** search
/ Aminet 12 / Aminet 12 (1996)(GTI - Schatztruhe)[!][Jun 1996].iso / Aminet / dev / e / eiffel.lha / flc / source / code.e < prev    next >
Encoding:
Text File  |  1996-01-13  |  8.2 KB  |  277 lines

  1.  
  2. -> Copyright © 1995, Guichard Damien.
  3.  
  4. -> New style of MC680x0 code generation
  5. -> This version is stricly limited to 68000 code
  6. -> Generators for abstract machines are derived from this by inheritance
  7. -> Two label range levels are provided: local range and global range
  8.  
  9. OPT MODULE
  10. OPT EXPORT
  11.  
  12. MODULE 'dos/doshunks'
  13.  
  14. ->  Condition codes
  15. ENUM   T, F, HI, LS, CC, CS, NE, EQ, VC, VS, PL, MI, GE, LT, GT, LE
  16.  
  17. -> Instruction mnemonics
  18.  
  19. CONST  XBCC   = $6000,  XDBCC  = $50C8,  XSCC   = $50C0
  20.  
  21. CONST  IADD   = $D000,  IADDI  = $0600,  IADDQ  = $5000,  IAND   = $C000,
  22.        IANDI  = $0200,  IASL   = $E100,  IASR   = $E000,  IBCC   = $6400,
  23.        IBCLR  = $0080,  IBCS   = $6500,  IBEQ   = $6700,  IBGE   = $6C00,
  24.        IBGT   = $6E00,  IBHI   = $6200,  IBLE   = $6F00,  IBLS   = $6300,
  25.        IBLT   = $6D00,  IBMI   = $6B00,  IBNE   = $6600,  IBPL   = $6A00,
  26.        IBRA   = $6000,  IBSET  = $00C0,  IBSR   = $6100,  IBTST  = $0000,
  27.        IBVC   = $6800,  IBVS   = $6900,  ICHK   = $4180,  ICLR   = $4200,
  28.        ICMP   = $B000,  ICMPI  = $0C00,  IDBCC  = $54C8,  IDBCS  = $55C8,
  29.        IDBEQ  = $57C8,  IDBF   = $51C8,  IDBGE  = $5CC8,  IDBGT  = $5EC8,
  30.        IDBHI  = $52C8,  IDBLE  = $5FC8,  IDBLS  = $53C8,  IDBLT  = $5DC8,
  31.        IDBMI  = $5BC8,  IDBNE  = $56C8,  IDBPL  = $5AC8,  IDBRA  = $50C8,
  32.        IDBT   = $50C8,  IDBVC  = $58C8,  IDBVS  = $59C8,  IDIVS  = $81C0,
  33.        IEOR   = $B100,  IEORI  = $0A00,  IEXG   = $C140,  IEXTW  = $4880,
  34.        IEXTL  = $48C0,  IJMP   = $4EC0,  IJSR   = $4E80,  ILEA   = $41C0,
  35.        ILINK  = $4E50,  ILSL   = $E108,  ILSR   = $E008,  IMOVEQ = $7000,
  36.        IMULS  = $C1C0,  INEG   = $4400,  INOP   = $4E71,  INOT   = $4600,
  37.        IOR    = $8000,  IORI   = $0000,  IPEA   = $4840,  IROL   = $E118,
  38.        IROR   = $E018,  IRTE   = $4E73,  IRTS   = $4E75,  ISCS   = $55C0,
  39.        ISEQ   = $57C0,  ISF    = $51C0,  ISGE   = $5CC0,  ISGT   = $5EC0,
  40.        ISHI   = $52C0,  ISLE   = $5FC0,  ISLS   = $53C0,  ISLT   = $5DC0,
  41.        ISMI   = $5BC0,  ISNE   = $56C0,  ISPL   = $5AC0,  ISRA   = $50C0,
  42.        IST    = $50C0,  ISVC   = $58C0,  ISVS   = $59C0,  ISUB   = $9000,
  43.        ISUBI  = $0400,  ISUBQ  = $5100,  ISWAP  = $4840,  ITRAP  = $4E40,
  44.        ITRAPV = $4E76,  ITST   = $4A00,  IUNLK  = $4E58
  45.  
  46. -> CPU Registers
  47.  
  48. ENUM   D_0, D_1, D_2, D_3, D_4, D_5, D_6, D_7
  49. ENUM   A_0, A_1, A_2, A_3, A_4, A_5, A_6, A_7
  50. CONST  SP = A_7
  51.  
  52. -> Addressing mode flag values
  53.  
  54. CONST  DREG   = 0, -> Data Register
  55.        ARDIR  = 1, -> Address Register Direct
  56.        ARIND  = 2, -> Address Register Indirect
  57.        ARPOST = 3, -> Address Register with Post-Increment
  58.        ARPRE  = 4, -> Address Register with Pre-Decrement
  59.        ARDISP = 5, -> Address Register with Displacement
  60.        ARDISX = 6, -> Address Register with Disp. & Index
  61.        MODE7  = 7, -> All other addressing modes
  62.        ABSW   = 0, -> Absolute Short (16-bit Address)
  63.        ABSL   = 1, -> Absolute Long (32-bit Address)
  64.        PCDISP = 2, -> Program Counter Relative, with Displacement
  65.        PCDISX = 3, -> Program Counter Relative, with Disp. & Index
  66.        IMM    = 4  -> Immediate
  67.  
  68. -> Size types
  69.  
  70. ENUM B, W, L
  71.  
  72.  
  73. -> hunk_code class
  74. OBJECT code
  75.   hunk:PTR TO INT
  76.   pc:PTR TO INT
  77.   globals:PTR TO LONG
  78.   global_refs:PTR TO LONG
  79.   g_ref:PTR TO LONG
  80.   locals:PTR TO LONG
  81.   local_refs:PTR TO LONG
  82.   l_ref:PTR TO LONG
  83. ENDOBJECT
  84.  
  85. -> Allocate code hunk
  86. PROC buffer(codesize) OF code
  87.   self.hunk:=NewR(codesize)
  88.   self.pc:=self.hunk
  89. ENDPROC
  90.  
  91. -> Flush code hunk into a file
  92. PROC flush(handle) OF code
  93.   DEF len
  94.   len:=self.pc-self.hunk+3 AND $FFFFFFFC
  95.   Write(handle,[HUNK_HEADER,0,1,0,0,Shr(len,2),HUNK_CODE,Shr(len,2)],32)
  96.   Write(handle,self.hunk,self.pc-self.hunk)
  97.   Write(handle,[0,0,0,0]:CHAR,len-self.pc+self.hunk)
  98.   Write(handle,[HUNK_END],4)
  99. ENDPROC
  100.  
  101. -> Allow global labels
  102. PROC global_labels(labels,refs) OF code
  103.   self.globals:=NewR(labels*SIZEOF LONG)
  104.   self.global_refs:=NewR(refs*2*SIZEOF LONG)
  105.   self.g_ref:=self.global_refs
  106. ENDPROC
  107.  
  108. -> Define a global label
  109. PROC define_global(label) OF code
  110.   self.globals[label]:=self.pc
  111. ENDPROC
  112.  
  113. -> Reference a global label
  114. PROC global_ref(label) OF code
  115.   self.g_ref[]:=self.pc
  116.   self.g_ref:=self.g_ref+SIZEOF LONG
  117.   self.g_ref[]:=label
  118.   self.g_ref:=self.g_ref+SIZEOF LONG
  119. ENDPROC
  120.  
  121. -> Resolve global references
  122. PROC resolve_globals() OF code
  123.   DEF lab:PTR TO LONG,adr
  124.   lab:=self.global_refs
  125.   WHILE lab<self.g_ref
  126.     PutInt((adr:=lab[]++)+2,self.globals[lab[]++]-adr-2)
  127.   ENDWHILE
  128.   self.g_ref:=self.global_refs
  129. ENDPROC
  130.  
  131. -> Allow local labels
  132. PROC local_labels(labels,refs) OF code
  133.   self.locals:=NewR(labels*SIZEOF LONG)
  134.   self.local_refs:=NewR(refs*2*SIZEOF LONG)
  135.   self.l_ref:=self.local_refs
  136. ENDPROC
  137.  
  138. -> Define a local label
  139. PROC define_local(label) OF code
  140.   self.locals[label]:=self.pc
  141. ENDPROC
  142.  
  143. -> Reference a local label
  144. PROC local_ref(label) OF code
  145.   self.l_ref[]:=self.pc
  146.   self.l_ref:=self.l_ref+SIZEOF LONG
  147.   self.l_ref[]:=label
  148.   self.l_ref:=self.l_ref+SIZEOF LONG
  149. ENDPROC
  150.  
  151. -> Resolve local references
  152. PROC resolve_locals() OF code
  153.   DEF lab:PTR TO LONG,adr
  154.   lab:=self.local_refs
  155.   WHILE lab<self.l_ref
  156.     PutInt((adr:=lab[]++)+2,self.locals[lab[]++]-adr-2)
  157.   ENDWHILE
  158.   self.l_ref:=self.local_refs
  159. ENDPROC
  160.  
  161. -> Put word into code
  162. -> Instructions: Bcc, DBcc, BRA, BSR, LINK, UNLK, RTS, RTE, RTR, SWAP, EXT
  163. -> Instructions: ILLEGAL, TRAP, TRAPV, NOP
  164. PROC putword(word) OF code
  165.   self.pc[]:=word
  166.   self.pc:=self.pc+SIZEOF INT
  167. ENDPROC
  168.  
  169. -> Put long into code
  170. PROC putlong(long) OF code
  171.   PutLong(self.pc,long)
  172.   self.pc:=self.pc+SIZEOF LONG
  173. ENDPROC
  174.  
  175. -> Put binary into code
  176. PROC putbinary(start,end) OF code
  177.   CopyMem(start,self.pc,end-start)
  178.   self.pc:=self.pc+end-start
  179. ENDPROC
  180.  
  181. -> Instruction format #1: xxxxxxxxsseeeeee
  182. -> Instructions: CLR, NEG, NOT, TST
  183. PROC putF1(op,size,data,mode,reg) OF code
  184.   self.pc[]:=op OR Shl(size,6) OR Shl(mode,3) OR reg
  185.   self.pc:=self.pc+SIZEOF INT
  186.   self.argument(size,data,mode,reg)
  187. ENDPROC
  188.  
  189. -> Instruction format #2: xxxxrrrxxxeeeeee
  190. -> Instructions: LEA, DIVS, DIVU, MULS, MULU, CHK
  191. PROC putF2(op,xdata,xmode,xreg,yreg) OF code
  192.   self.pc[]:=op OR Shl(yreg,9) OR Shl(xmode,3) OR xreg
  193.   self.pc:=self.pc+SIZEOF INT
  194.   self.argument(W,xdata,xmode,xreg)
  195. ENDPROC
  196.  
  197. -> Instruction format #3: xxxxxxxxxxeeeeee
  198. -> Instructions: PEA, JSR, JMP, Scc
  199. PROC putF3(op,data,mode,reg) OF code
  200.   self.pc[]:=op OR Shl(mode,3) OR reg
  201.   self.pc:=self.pc+SIZEOF INT
  202.   self.argument(W,data,mode,reg)
  203. ENDPROC
  204.  
  205. -> Instruction format #4: 00sseeeeeeeeeeee
  206. -> Instructions: MOVE, MOVEA
  207. PROC putF4(size,xdata,xmode,xreg,ydata,ymode,yreg) OF code
  208.   self.pc[]:= Shl(IF size=B THEN %1 ELSE size OR %10,12) OR
  209.               Shl(yreg,9) OR Shl(ymode,6) OR Shl(xmode,3) OR xreg
  210.   self.pc:=self.pc+SIZEOF INT
  211.   self.argument(size,xdata,xmode,xreg)
  212.   self.argument(size,ydata,ymode,yreg)
  213. ENDPROC
  214.  
  215. -> Instruction format #5: xxxxrrrmmmeeeeee
  216. -> Instructions: OR, SUB, SUBA, CMP, CMPA, EOR, AND, ADD, ADDA
  217. PROC putF5(op,size,xdata,xmode,xreg,yreg) OF code
  218.   self.pc[]:=op OR Shl(yreg,9) OR Shl(size,6) OR Shl(xmode,3) OR xreg
  219.   self.pc:=self.pc+SIZEOF INT
  220.   self.argument(size,xdata,xmode,xreg)
  221. ENDPROC
  222.  
  223. -> Instruction format #6: xxxxxxxxsseeeeee
  224. -> Instructions: ORI, SUBI, CMPI, EORI, ANDI, ADDI
  225. PROC putF6(op,size,xdata,ydata,ymode,yreg) OF code
  226.   self.pc[]:=op OR Shl(size,6) OR Shl(ymode,3) OR yreg
  227.   self.argument(size,xdata,MODE7,IMM)
  228.   self.argument(size,ydata,ymode,yreg)
  229. ENDPROC
  230.  
  231. -> Instruction format #7: xxxxdddxsseeeeee
  232. -> Instructions: ADDQ, SUBQ
  233. PROC putF7(op,size,xdata,ydata,ymode,yreg) OF code
  234.   self.pc[]:=op OR Shl(xdata,9) OR Shl(size,6) OR Shl(ymode,3) OR yreg
  235.   self.pc:=self.pc+SIZEOF INT
  236.   self.argument(size,ydata,ymode,yreg)
  237. ENDPROC
  238.  
  239.  
  240. -> PRIVATE part
  241.  
  242. -> Instruction arguments
  243. PROC argument(size,data,mode,reg) OF code
  244.   IF (mode = ARDISP) OR (mode = ARDISX)
  245.     self.pc[]:=data
  246.     self.pc:=self.pc+SIZEOF INT
  247.   ELSEIF mode = MODE7
  248.     SELECT reg
  249.     CASE ABSW
  250.       self.pc[]:=data
  251.       self.pc:=self.pc+SIZEOF INT
  252.     CASE ABSL
  253.       PutLong(self.pc,data)
  254.       self.pc:=self.pc+SIZEOF LONG
  255.     CASE PCDISP
  256.       self.pc[]:=data
  257.       self.pc:=self.pc+SIZEOF INT
  258.     CASE PCDISX
  259.       self.pc[]:=data
  260.       self.pc:=self.pc+SIZEOF INT
  261.     CASE IMM
  262.       SELECT size
  263.       CASE B
  264.         self.pc[]:=data
  265.         self.pc:=self.pc+SIZEOF INT
  266.       CASE W
  267.         self.pc[]:=data
  268.         self.pc:=self.pc+SIZEOF INT
  269.       CASE L
  270.         PutLong(self.pc,data)
  271.         self.pc:=self.pc+SIZEOF LONG
  272.       ENDSELECT
  273.     ENDSELECT
  274.   ENDIF
  275. ENDPROC
  276.  
  277.